---------------------------------------------------------------
File name   :  vv_ahblite_agent_h.e
Title       :  Agent declaration
Project     :  vv_ahblite eVC
Developers  :  stefan,filip
Created     :  Fri Jul  27.07.2011.
Description :  This file declares the agent unit.
Notes       :  This unit is the base type for all agents (master
    :   or slave).
---------------------------------------------------------------
Copyright  (c)2011
---------------------------------------------------------------

<'
package vv_ahblite;

-- ==========================================================================
-- Base unit for eVC agents
-- ==========================================================================
extend vv_ahblite_agent {

    -- Name of the environment
    env_name      :   vv_ahblite_env_name_t;

    -- This field is the logical name of the agent. This field is
    -- automatically constrained by the eVC. Do not constrain it
    -- manually.
    name          : vv_ahblite_agent_name_t;
    
    p_env         : vv_ahblite_env;
    p_smp         : vv_ahblite_smp;
    !p_bus_monitor : vv_ahblite_bus_monitor;
    p_sys_smp     : vv_ahblite_system_smp;
    
    logger        : message_logger is instance;
       keep soft logger.verbosity == NONE;
    
    active_passive: erm_active_passive_t;
       keep soft active_passive == ACTIVE;

    has_checks    : bool;
    has_coverage  : bool;
    
    -- By default, has_checks and has_coverage are false for active agents.
    -- ???? should we edit this so that active does checks and coverage????
    keep active_passive == ACTIVE => soft has_checks == FALSE;
    keep active_passive == ACTIVE => soft has_coverage == FALSE;
    keep active_passive == PASSIVE => soft has_checks == TRUE;
    keep active_passive == PASSIVE => soft has_coverage == TRUE;
    
    event clk is @p_sys_smp.clk;
    event reset_start is @p_sys_smp.reset_start;
    event reset_end is @p_sys_smp.reset_end;
    
    on reset_start {
        reset_start();
    };
    
    on reset_end {
        reset_end();
    };
    
    -- These methods are extended in the different agent units
    -- to implement appropriate reset behavior
    reset_start() is empty;
    reset_end() is empty;
    
    -- Agent color to be used in messages
    agents_vt_style: vt_style;
    
    -- Agent name to be used in messages
    agent_message_name : string;
        keep soft agent_message_name == name.as_a(string);
    
    -- This method returns the name of the agent instance.
    short_name(): string is only {
        result = agent_message_name;
    }; 
    
    -- This method determines the message color.
    short_name_style(): vt_style is {
        return agents_vt_style;
    };
     
};

'>
<'
-- =================================================================
-- The master agents are proactive agents. Proactive agents
-- initiate transactions.The following code customizes master
-- agents.
-- =================================================================

extend vv_ahblite_master {
    
   keep agents_vt_style == CYAN;
    
    -- This instance of the agent monitor handles agent-specific
    -- bus activity.
    agent_monitor : vv_ahblite_master_monitor is instance;
        keep agent_monitor.agent_name    == read_only(name);
        keep agent_monitor.p_agent       == read_only(me);
        keep agent_monitor.p_env         == read_only(p_env);
        keep agent_monitor.env_name      == read_only(env_name);
        keep agent_monitor.has_checks    == read_only(has_checks);
        keep agent_monitor.has_coverage  == read_only(has_coverage);
    
    connect_pointers() is also {
        agent_monitor.p_bus_monitor = p_bus_monitor;
    }; 
    
    when ACTIVE vv_ahblite_master {
       
        -- This is the sequence driver for an active master agent.
        driver: vv_ahblite_master_driver_u is instance;
            keep driver.p_master == read_only(me);
            keep driver.p_env == read_only(p_env); 
            keep driver.env_name == read_only(env_name);
            keep driver.master_name == read_only(name);
        
        -- BFM for an active master agent
        bfm : vv_ahblite_master_bfm is instance;
            keep bfm.p_env         == read_only(p_env);
            keep bfm.env_name      == read_only(env_name);
            keep bfm.p_smp         == read_only(p_smp);
            keep bfm.p_master      == read_only(me);
            keep bfm.p_sys_smp     == read_only(p_sys_smp);
        
        connect_pointers() is also {
            bfm.p_driver = driver;
            bfm.p_bus_monitor = p_bus_monitor;
            driver.p_bus_monitor = p_bus_monitor;
        }; 
      };
    
};
'>
<'
-- ==========================================================================
-- The slave agents are reactive agents. Reactive agents only
-- respond to requests. The following code customizes slave agent.
-- ==========================================================================
extend vv_ahblite_slave {
    
    -- **********************************************************************
    -- IVB-NOTE : OPTIONAL : slave agent : 06 Agents 
    -- ----------------------------------------------------------------------
    -- Use this section to add slave fields, events,
    -- and methods.
    -- **********************************************************************
    
    -- Constrain th master messages color
    keep agents_vt_style == GREEN;
    
    -- This instance of the agent monitor handles agent-specific
    -- bus activity.
    agent_monitor : vv_ahblite_slave_monitor is instance;
        keep agent_monitor.agent_name    == read_only(name);
        keep agent_monitor.p_agent       == read_only(me);
        keep agent_monitor.p_env         == read_only(p_env);
        keep agent_monitor.env_name      == read_only(env_name);
        keep agent_monitor.has_checks    == read_only(has_checks);
        keep agent_monitor.has_coverage  == read_only(has_coverage);
    
    connect_pointers() is also {
        agent_monitor.p_bus_monitor = p_bus_monitor;
    };
    
    when ACTIVE vv_ahblite_slave {
       
        -- This is the sequence driver for an active slave agent.
        driver: vv_ahblite_slave_driver_u is instance;
            keep driver.p_slave == read_only(me);
            keep driver.p_env == read_only(p_env); 
            keep driver.env_name == read_only(env_name);
            keep driver.slave_name == read_only(name);
        
        -- BFM for an active master agent
        bfm : vv_ahblite_slave_bfm is instance;
            keep bfm.p_env         == read_only(p_env);
            keep bfm.env_name      == read_only(env_name);
            keep bfm.p_smp         == read_only(p_smp);
            keep bfm.p_slave       == read_only(me);
            keep bfm.p_sys_smp     == read_only(p_sys_smp);    
        
        connect_pointers() is also {
            bfm.p_driver = driver;
            bfm.p_bus_monitor = p_bus_monitor;
            driver.p_bus_monitor = p_bus_monitor;
        };
    };
    -- This is a memory model used to generate read data according
    -- to past write data.
    mem : vr_ad_mem;
    
    -- If this field is TRUE then write data will be written into the memory
    -- and read data will be taken from the memory. If this field
    -- is FALSE, then read data must be supplied by the slave sequence.
    use_mem : bool;
        keep soft use_mem == FALSE;-- @@ da li da ostavim da bude TRUE?
    
    write(addr: vv_ahblite_addr_t, data : vv_ahblite_data_t) is {
        var i : list of byte = pack(packing.low, data); --@@ TODOmogu da stavim i package.high, u sustini nije bitno 
        mem.update((addr.as_a(uint) - min_addr),i,{});
    };
    
    read(addr : vv_ahblite_addr_t) : vv_ahblite_data_t is {
        unpack(packing.low, mem.fetch((addr.as_a(uint) - min_addr),4), result);
    };
     
    -- This field defines the lower boundary of the slave address
    -- range.
    min_addr : vv_ahblite_addr_t;
    max_addr : vv_ahblite_addr_t;
        keep max_addr >= min_addr;

    package in_range(addr : vv_ahblite_addr_t) : bool is undefined;
    
    --HSEL port, should be instantiated when configuring a slave agent
    h_sel : inout simple_port of bit;
    h_readyout : inout simple_port of bit ;
    h_resp  : inout simple_port of bit ;
    h_rdata : inout simple_port of vv_ahblite_data_t ;
    
};
'>
